package com.flycms.web.system.rest;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.flycms.core.base.BaseController;
import com.flycms.core.entity.PagingParam;
import com.flycms.core.entity.RestDataVo;
import com.flycms.core.utils.web.utils.CommonUtils;
import com.flycms.module.soft.model.Case;
import com.flycms.module.soft.model.Soft;
import com.flycms.module.soft.model.SoftCategory;
import com.flycms.module.soft.service.SoftCaseService;
import com.flycms.module.soft.service.SoftCategoryService;
import com.flycms.module.soft.service.SoftService;
import com.flycms.module.solution.model.Solution;
import com.flycms.module.solution.model.SolutionFunction;
import com.flycms.module.solution.model.SolutionParam;
import com.flycms.module.solution.model.SolutionPartner;
import com.flycms.module.solution.service.SolutionFunctionService;
import com.flycms.module.solution.service.SolutionPartnerService;
import com.flycms.module.solution.service.SolutionService;

/**
 *
 * <br/>Copyright 2020
 * <br/>All rights reserved
 * @author 沁言訫語
 * @version 2020年3月11日
 * @Date 2020年3月11日
 */

@RestController
@RequestMapping("/solution/system")
public class AdminSolutionController extends BaseController {

    private static final Logger logger = LogManager.getLogger(AdminSolutionController.class);
    
    @Autowired
    protected SolutionService solutionService;
    
    @Autowired
    protected SolutionFunctionService solutionFunctionService;
    
    @Autowired
    protected SolutionPartnerService solutionPartnerService;
    
    @Autowired
    protected SoftCaseService softCaseService;
    
    @Autowired
    protected SoftService softService;
    
    @Autowired
    protected SoftCategoryService categoryService;
    
    @PostMapping(value = {"/add"})
    public RestDataVo addSolution(@Valid @RequestBody Solution solution, BindingResult errors) {
        RestDataVo rest = null;
        String validResult = CommonUtils.validParams(errors, logger);
        if (StringUtils.isNotEmpty(validResult)) {
            return RestDataVo.ERROR(validResult);
        }
        Solution s = new Solution();
        s.setCategoryId(solution.getCategoryId());
        s.setTitle(solution.getTitle());
        s.setDescription(solution.getDescription());
        s.setImgPath(solution.getImgPath());
        s.setCreateTime(new Date());
        s.setUpdateTime(new Date());
        try {
            SoftCategory cate = categoryService.queryByPk(s.getCategoryId());
            if (cate == null) {
                rest = RestDataVo.ERROR("解决方案分类不存在");
            } else {
                solutionService.addSolution(s);
                rest = RestDataVo.OK(s);
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("新增解决方案异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/edit/{solutionId}"})
    public RestDataVo updateSolution(@PathVariable("solutionId") Integer solutionId,
            @Valid @RequestBody Solution solution, BindingResult errors) {
        RestDataVo rest = null;
        String validResult = CommonUtils.validParams(errors, logger);
        if (StringUtils.isNotEmpty(validResult)) {
            return RestDataVo.ERROR(validResult);
        }
        Solution s = new Solution();
        s.setId(solutionId);
        s.setCategoryId(solution.getCategoryId());
        s.setTitle(solution.getTitle());
        s.setDescription(solution.getDescription());
        s.setImgPath(solution.getImgPath());
        s.setScenarios(solution.getScenarios());
        s.setAdvantage(solution.getAdvantage());
        s.setUpdateTime(new Date());
        try {
            SoftCategory cate = categoryService.queryByPk(s.getCategoryId());
            if (cate == null) {
                rest = RestDataVo.ERROR("解决方案分类不存在");
            } else {
                solutionService.updateSolution(s);
                rest = RestDataVo.OK(s);
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("修改解决方案异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/remove/{solutionId}"})
    public RestDataVo removeSolution(@PathVariable("solutionId") Integer solutionId) {
        RestDataVo rest = null;
        try {
            Solution solution = new Solution();
            solution.setId(solutionId);
            solutionService.removeSolution(solution);
            rest = RestDataVo.OK("删除成功");
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("修改解决方案异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/f/add/{id}"})
    public RestDataVo addSolutionFunction(
            @PathVariable("id") Integer id, @RequestBody SolutionParam param) {
        RestDataVo rest = null;
        List<SolutionFunction> funcList = param.getSolutionFunctions();
        if (funcList == null || funcList.size() == 0) {
            return RestDataVo.ERROR("缺少方案功能列表");
        }
        try {
            Solution s = solutionService.querySolutionById(id);
            if (s == null) {
                rest = RestDataVo.ERROR("解决方案不存在");
            } else {
                solutionFunctionService.addSolutionFunctions(funcList, id);
                rest = RestDataVo.OK("新增方案功能成功");
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("新增方案功能异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/f/edit/{id}", "/f/edit/{id}/{single}/single"})
    public RestDataVo updateSolutionFunction(
            @PathVariable("id") Integer id,
            @PathVariable(value = "single", required = false) Boolean single,
            @RequestBody SolutionParam param) {
        RestDataVo rest = null;
        List<SolutionFunction> funcList = param.getSolutionFunctions();
        if (funcList == null || funcList.size() == 0) {
            return RestDataVo.ERROR("缺少方案功能列表");
        }
        try {
            Solution s = solutionService.querySolutionById(id);
            if (s == null) {
                rest = RestDataVo.ERROR("解决方案不存在");
            } else {
                solutionFunctionService.updateSolutionFunctions(funcList, id, single);
                rest = RestDataVo.OK("修改方案功能成功");
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("修改方案功能异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/f/remove/{id}"})
    public RestDataVo removeSolutionFunction(
            @PathVariable("id") Integer id,
            @RequestParam(value = "functionId", required = false) Integer functionId) {
        RestDataVo rest = null;
        try {
            Solution s = solutionService.querySolutionById(id);
            if (s == null) {
                rest = RestDataVo.ERROR("删除方案不存在");
            } else {
                solutionFunctionService.removeSolutionFunctions(id, functionId);
                rest = RestDataVo.OK("删除方案功能成功");
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("删除方案功能异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/p/add/{id}"})
    public RestDataVo addSolutionPartner(@PathVariable("id") Integer id, @RequestBody SolutionParam param) {
        RestDataVo rest = null;
        List<SolutionPartner> partners = param.getSolutionPartners();
        if (partners == null || partners.size() == 0) {
            return RestDataVo.ERROR("缺少方案功能列表");
        }
        try {
            Solution s = solutionService.querySolutionById(id);
            if (s == null) {
                rest = RestDataVo.ERROR("解决方案不存在");
            } else {
                solutionPartnerService.addSolutionPartners(partners, id);
                rest = RestDataVo.OK("新增方案功能成功");
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("新增方案合作伙伴异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/p/edit/{id}", "/p/edit/{id}/{single}/single"})
    public RestDataVo updateSolutionPartner(@PathVariable("id") Integer id,
            @PathVariable(value = "single", required = false) Boolean single,
            @RequestBody SolutionParam param) {
        RestDataVo rest = null;
        List<SolutionPartner> partners = param.getSolutionPartners();
        if (partners == null || partners.size() == 0) {
            return RestDataVo.ERROR("缺少方案功能列表");
        }
        try {
            Solution s = solutionService.querySolutionById(id);
            if (s == null) {
                rest = RestDataVo.ERROR("解决方案不存在");
            } else {
                solutionPartnerService.updateSolutionPartners(partners, id, single);
                rest = RestDataVo.OK("修改方案合作伙伴成功");
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("修改方案合作伙伴异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/p/remove/{id}"})
    public RestDataVo removeSolutionPartner(@PathVariable("id") Integer id,
            @RequestParam(value = "partnerId", required = false) Integer partnerId) {
        RestDataVo rest = null;
        try {
            Solution s = solutionService.querySolutionById(id);
            if (s == null) {
                rest = RestDataVo.ERROR("解决方案不存在");
            } else {
                solutionPartnerService.removeSolutionPartners(id, partnerId);
                rest = RestDataVo.OK("删除方案合作伙伴成功");
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("删除方案合作伙伴异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/c/add/{id}", "/c/add/{id}/{single}/single"})
    public RestDataVo addSolutionCase(@PathVariable("id") Integer id,
            @PathVariable(value = "single", required = false) Boolean single,
            @RequestBody SolutionParam param) {
        RestDataVo rest = null;
        List<Integer> ids = param.getCaseIds();
        if (ids == null || ids.size() == 0) {
            return RestDataVo.ERROR("缺少用户案例列表");
        }
        try {
            List<Case> caseList = softCaseService.queryByIds(ids);
            if (caseList == null || ids.size() != caseList.size()) {
                rest = RestDataVo.ERROR("部分用户案例不存在");
                return rest;
            }
            Solution s = solutionService.querySolutionById(id);
            if (s == null) {
                rest = RestDataVo.ERROR("解决方案不存在");
            } else {
                List<Case> haveList = solutionService.getSolutionCase(s.getId(), null, null);
                List<Integer> idsHave = new ArrayList<>();
                List<Integer> idsTarget = new ArrayList<>();
                for (Case st : haveList) {
                    idsHave.add(st.getId());
                }
                for (Integer i : ids) {
                    if (!idsHave.contains(i)) {
                        idsTarget.add(i);
                    }
                }
                if (idsTarget.size() > 0) {
                    solutionService.addSolutionCase(idsTarget, id, single);
                }
                rest = RestDataVo.OK("新增解决方案用户案例成功");
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("新增解决方案用户案例异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/c/edit/{id}"})
    public RestDataVo updateSolutionCase(@PathVariable("id") Integer id,
            @RequestBody SolutionParam param) {
        RestDataVo rest = null;
        List<Integer> ids = param.getCaseIds();
        if (ids == null || ids.size() == 0) {
            return RestDataVo.ERROR("缺少用户案例列表");
        }
        try {
            List<Case> caseList = softCaseService.queryByIds(ids);
            if (caseList == null || ids.size() != caseList.size()) {
                rest = RestDataVo.ERROR("部分用户案例不存在");
                return rest;
            }
            Solution s = solutionService.querySolutionById(id);
            if (s == null) {
                rest = RestDataVo.ERROR("解决方案不存在");
            } else {
                solutionService.updateSolutionCase(ids, id);
                rest = RestDataVo.OK("修改解决方案用户案例成功");
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("新增解决方案用户案例异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/c/remove/{id}"})
    public RestDataVo removeolutionCase(@PathVariable("id") Integer id,
            @RequestParam(value = "caseId", required = false) Integer caseId) {
        RestDataVo rest = null;
        try {
            Solution s = solutionService.querySolutionById(id);
            if (s == null) {
                rest = RestDataVo.ERROR("解决方案不存在");
            } else {
                solutionService.removeSolutionCase(id, caseId);
                rest = RestDataVo.OK("删除解决方案用户案例成功");
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("删除解决方案用户案例异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/s/add/{id}", "/s/add/{id}/{single}/single"})
    public RestDataVo addSolutionStruct(@PathVariable("id") Integer id,
            @PathVariable(value = "single", required = false) Boolean single,
            @RequestBody SolutionParam param) {
        RestDataVo rest = null;
        List<Integer> ids = param.getProductIds();
        if (ids == null || ids.size() == 0) {
            return RestDataVo.ERROR("缺少产品列表");
        }
        try {
            List<Soft> softList = softService.queryByIds(ids);
            if (softList == null || ids.size() != softList.size()) {
                rest = RestDataVo.ERROR("部分产品不存在");
                return rest;
            }
            Solution s = solutionService.querySolutionById(id);
            if (s == null) {
                rest = RestDataVo.ERROR("解决方案不存在");
            } else {
                List<Soft> caseList = solutionService.getSolutionProduct(s.getId(), null, null);
                List<Integer> idsHave = new ArrayList<>();
                List<Integer> idsTarget = new ArrayList<>();
                for (Soft st : caseList) {
                    idsHave.add(st.getId());
                }
                for (Integer i : ids) {
                    if (!idsHave.contains(i)) {
                        idsTarget.add(i);
                    }
                }
                
                solutionService.addSolutionProduct(idsTarget, id, param.getScenarios(), param.getAdvantage(), single);
                rest = RestDataVo.OK("新增解决方案架构成功");
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("新增解决方案架构异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/s/edit/{id}"})
    public RestDataVo updateSolutionStruct(@PathVariable("id") Integer id,
            @RequestBody SolutionParam param) {
        RestDataVo rest = null;
        List<Integer> ids = param.getProductIds();
        if (ids == null || ids.size() == 0) {
            return RestDataVo.ERROR("缺少产品列表");
        }
        try {
            List<Soft> softList = softService.queryByIds(ids);
            if (softList == null || ids.size() != softList.size()) {
                rest = RestDataVo.ERROR("部分产品不存在");
                return rest;
            }
            Solution s = solutionService.querySolutionById(id);
            if (s == null) {
                rest = RestDataVo.ERROR("解决方案不存在");
            } else {
                solutionService.updateSolutionProduct(ids, id);
                rest = RestDataVo.OK("新增解决方案架构成功");
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("新增解决方案架构异常");
        }
        return rest;
    }
    
    @PostMapping(value = {"/s/remove/{id}"})
    public RestDataVo removeSolutionStruct(@PathVariable("id") Integer id,
            @RequestParam(value = "productId", required = false) Integer productId) {
        RestDataVo rest = null;
        try {
            Solution s = solutionService.querySolutionById(id);
            if (s == null) {
                rest = RestDataVo.ERROR("解决方案不存在");
            } else {
                solutionService.removeSolutionProduct(id, productId);
                rest = RestDataVo.OK("删除解决方案架构成功");
            }
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("删除解决方案架构异常");
        }
        return rest;
    }
    
    @GetMapping(value = { "/list/{categoryId}", "/list" })
    public RestDataVo getSolutionList(@PathVariable(value = "categoryId", required = false) Integer categoryId,
            @RequestParam(value = "title", required = false) String title,
            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
            @RequestParam(value = "pageSize", required = false) Integer pageSize) {
        PagingParam paging = CommonUtils.validParam(pageIndex, pageSize);
        RestDataVo rest = null;
        try {
            List<Solution> solutionList = solutionService.getSolutionList(categoryId, title, paging.getOffset(),
                    paging.getRows());
            int count = solutionService.getSolutionCount(categoryId, title);
            rest = RestDataVo.PAGE(solutionList, paging.getPageIndex(), paging.getPageSize(), count);
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("获取解决方案列表异常");
        }
        return rest;
    }

    @GetMapping(value = {"/{solutionId}/info"})
    public RestDataVo getSolutionInfo(@PathVariable("solutionId") Integer solutionId) {
        RestDataVo rest = null;
        try {
            Solution s = solutionService.querySolutionById(solutionId);
            rest = RestDataVo.OK(s);
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("获取解决方案异常");
        }
        return rest;
    }
    
    @GetMapping(value = { "/f/list/{solutionId}" })
    public RestDataVo getSolutionFunctionList(@PathVariable("solutionId") Integer solutionId,
            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
            @RequestParam(value = "pageSize", required = false) Integer pageSize) {
        PagingParam paging = CommonUtils.validParam(pageIndex, pageSize);
        RestDataVo rest = null;
        try {
            List<SolutionFunction> list = solutionFunctionService.getSolutionFunctionList(solutionId,
                    paging.getOffset(), paging.getRows());
            int count = solutionFunctionService.getSolutionFunctionCount(solutionId);
            rest = RestDataVo.PAGE(list, paging.getPageIndex(), paging.getPageSize(), count);
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("获取方案功能异常");
        }
        return rest;
    }

    @GetMapping(value = { "/p/list/{solutionId}" })
    public RestDataVo getSolutionPartnerList(@PathVariable("solutionId") Integer solutionId,
            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
            @RequestParam(value = "pageSize", required = false) Integer pageSize) {
        PagingParam paging = CommonUtils.validParam(pageIndex, pageSize);
        RestDataVo rest = null;
        try {
            List<SolutionPartner> list = solutionPartnerService.getSolutionPartnerList(solutionId, paging.getOffset(),
                    paging.getRows());
            int count = solutionPartnerService.getSolutionPartnerCount(solutionId);
            rest = RestDataVo.PAGE(list, paging.getPageIndex(), paging.getPageSize(), count);
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("获取方案合作伙伴异常");
        }
        return rest;
    }

    @GetMapping(value = { "/s/list/{solutionId}" })
    public RestDataVo getSolutionStructList(@PathVariable("solutionId") Integer solutionId,
            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
            @RequestParam(value = "pageSize", required = false) Integer pageSize) {
        PagingParam paging = CommonUtils.validParam(pageIndex, pageSize);
        RestDataVo rest = null;
        try {
            List<Soft> softList = solutionService.getSolutionProduct(solutionId, paging.getOffset(), paging.getRows());
            int count = solutionService.getSolutionProductCount(solutionId);
            rest = RestDataVo.PAGE(softList, paging.getPageIndex(), paging.getPageSize(), count);
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("获取方案架构异常");
        }
        return rest;
    }

    @GetMapping(value = { "/c/list/{solutionId}" })
    public RestDataVo getSolutionCaseList(@PathVariable("solutionId") Integer solutionId,
            @RequestParam(value = "pageIndex", required = false) Integer pageIndex,
            @RequestParam(value = "pageSize", required = false) Integer pageSize) {
        PagingParam paging = CommonUtils.validParam(pageIndex, pageSize);
        RestDataVo rest = null;
        try {
            List<Case> caseList = solutionService.getSolutionCase(solutionId, paging.getOffset(), paging.getRows());
            int count = solutionService.getSolutionCaseCount(solutionId);
            rest = RestDataVo.PAGE(caseList, paging.getPageIndex(), paging.getPageSize(), count);
        } catch (Exception e) {
            logger.error("", e);
            rest = RestDataVo.ERROR("获取方案用户案例异常");
        }
        return rest;
    }
    
}
